# refactor of braket.py
# 26/5/2012

import unittest

BRACKETS = "()[]{}<>"

def word(lst):
	s = ""
	for element in lst:
		s+=str(element)
	return s

opened = word([BRACKETS[i] for i in range(0, len(BRACKETS), 2)])
closed = word([BRACKETS[i] for i in range(1, len(BRACKETS), 2)])

def goodbrackets(string):
	'''takes a string with only BRACKETS and check if they are in correct balance'''
	if not string : 
		return False
	if not len(string)%2==0:
		return False

	# for each brackets create a stack, push if there is a open brakets, pop otherways.
	stack = []
	for char in string:
		if char in opened:
			stack.append(char)
		if char in closed: 
			try: 
				index = closed.index(char)
				if stack[-1]==opened[index]: stack.pop()
				else:return False
			except IndexError: return False

	# if stacks are empty string is in a good balance.
	return not stack

class test(unittest.TestCase):
	bads = ["",
		None,
		"(", 
		")", 
		"((",
		"(][)",
		"(<(>))"
		"[)()(]",
		"<>)(<>",
		"{(<[>])()}"
		]
	goods = ["()",
		 "()()",
		 "[()()]",
		 "{[][[()<()>]]}",
		 "[<([])<>(()())>]"
		]

	def test(self):
		print("========= test bads")
		for test in self.bads: self.assertTrue(not goodbrackets(test), "test: "+str(test))
		print("========= test goods")		
		for test in self.goods: self.assertTrue(goodbrackets(test))

if __name__ == "__main__":
	unittest.main()


